package cn.bonoon.kernel.bytecode.asm;

import org.springframework.asm.ClassWriter;
import org.springframework.asm.MethodVisitor;
import org.springframework.asm.Opcodes;

import cn.bonoon.kernel.IdGenerator;
import cn.bonoon.kernel.KernelClassLoader;

public abstract class AbstractClassWriter extends ClassWriter implements Opcodes{
//	private static long count = 0;
//	protected static final String 
	/**
	 * 如果需要调用到父类的一些方法，就需要指定父类的路径
	 */
	protected String parentPath;
	protected String classPath;
	
	protected String className;
	protected String signature;
	/**
	 * 子类在解析转换方法的过程中，可以随时向构造函数里添加需要进行初始化处理的语句
	 */
	protected MethodVisitor constructor;
	protected final String[] interfaces;
	public AbstractClassWriter(String... interfaces) {
		super(ClassWriter.COMPUTE_MAXS);
		this.interfaces = interfaces;
		
	}
	
	public Class<?> buildClass()throws Exception{
		visit(V1_6, ACC_PUBLIC, classPath, signature, parentPath, interfaces);  
	    this.constructor = visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 
        // 代码开始：必须  
        constructor.visitCode();  
        constructor.visitVarInsn(ALOAD, 0);  
        constructor.visitMethodInsn(INVOKESPECIAL, parentPath, "<init>", "()V", false); 
        
        internalBuild();
        
        constructor.visitInsn(RETURN);  
        constructor.visitMaxs(0, 0);// 计算栈和局部变量最大空间：必须  
        constructor.visitEnd();// 代码结束：必须  
        visitEnd();
        return KernelClassLoader.register(className, toByteArray());
	}
	
	protected abstract void internalBuild() throws Exception;
	
	public String assignField(final int access, final String desc, final String signature, final Object value){
		String fieldName = IdGenerator.build();
		visitField(access, fieldName, desc, signature, value).visitEnd();
		return fieldName;
	}
}
